home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / amigaos4_only / mpega_libmad / mad / timer.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  11KB  |  488 lines

  1. /*
  2.  * libmad - MPEG audio decoder library
  3.  * Copyright (C) 2000-2003 Underbit Technologies, Inc.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  * $Id: timer.c,v 1.17 2003/05/27 22:40:37 rob Exp $
  20.  */
  21.  
  22. # ifdef HAVE_CONFIG_H
  23. #  include "config.h"
  24. # endif
  25.  
  26. # include "global.h"
  27.  
  28. # include <stdio.h>
  29.  
  30. # ifdef HAVE_ASSERT_H
  31. #  include <assert.h>
  32. # endif
  33.  
  34. # include "timer.h"
  35.  
  36. mad_timer_t const mad_timer_zero = { 0, 0 };
  37.  
  38. /*
  39.  * NAME:    timer->compare()
  40.  * DESCRIPTION:    indicate relative order of two timers
  41.  */
  42. int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
  43. {
  44.   signed long diff;
  45.  
  46.   diff = timer1.seconds - timer2.seconds;
  47.   if (diff < 0)
  48.     return -1;
  49.   else if (diff > 0)
  50.     return +1;
  51.  
  52.   diff = timer1.fraction - timer2.fraction;
  53.   if (diff < 0)
  54.     return -1;
  55.   else if (diff > 0)
  56.     return +1;
  57.  
  58.   return 0;
  59. }
  60.  
  61. /*
  62.  * NAME:    timer->negate()
  63.  * DESCRIPTION:    invert the sign of a timer
  64.  */
  65. void mad_timer_negate(mad_timer_t *timer)
  66. {
  67.   timer->seconds = -timer->seconds;
  68.  
  69.   if (timer->fraction) {
  70.     timer->seconds -= 1;
  71.     timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
  72.   }
  73. }
  74.  
  75. /*
  76.  * NAME:    timer->abs()
  77.  * DESCRIPTION:    return the absolute value of a timer
  78.  */
  79. mad_timer_t mad_timer_abs(mad_timer_t timer)
  80. {
  81.   if (timer.seconds < 0)
  82.     mad_timer_negate(&timer);
  83.  
  84.   return timer;
  85. }
  86.  
  87. /*
  88.  * NAME:    reduce_timer()
  89.  * DESCRIPTION:    carry timer fraction into seconds
  90.  */
  91. static
  92. void reduce_timer(mad_timer_t *timer)
  93. {
  94.   timer->seconds  += timer->fraction / MAD_TIMER_RESOLUTION;
  95.   timer->fraction %= MAD_TIMER_RESOLUTION;
  96. }
  97.  
  98. /*
  99.  * NAME:    gcd()
  100.  * DESCRIPTION:    compute greatest common denominator
  101.  */
  102. static
  103. unsigned long gcd(unsigned long num1, unsigned long num2)
  104. {
  105.   unsigned long tmp;
  106.  
  107.   while (num2) {
  108.     tmp  = num2;
  109.     num2 = num1 % num2;
  110.     num1 = tmp;
  111.   }
  112.  
  113.   return num1;
  114. }
  115.  
  116. /*
  117.  * NAME:    reduce_rational()
  118.  * DESCRIPTION:    convert rational expression to lowest terms
  119.  */
  120. static
  121. void reduce_rational(unsigned long *numer, unsigned long *denom)
  122. {
  123.   unsigned long factor;
  124.  
  125.   factor = gcd(*numer, *denom);
  126.  
  127.   assert(factor != 0);
  128.  
  129.   *numer /= factor;
  130.   *denom /= factor;
  131. }
  132.  
  133. /*
  134.  * NAME:    scale_rational()
  135.  * DESCRIPTION:    solve numer/denom == ?/scale avoiding overflowing
  136.  */
  137. static
  138. unsigned long scale_rational(unsigned long numer, unsigned long denom,
  139.                  unsigned long scale)
  140. {
  141.   reduce_rational(&numer, &denom);
  142.   reduce_rational(&scale, &denom);
  143.  
  144.   assert(denom != 0);
  145.  
  146.   if (denom < scale)
  147.     return numer * (scale / denom) + numer * (scale % denom) / denom;
  148.   if (denom < numer)
  149.     return scale * (numer / denom) + scale * (numer % denom) / denom;
  150.  
  151.   return numer * scale / denom;
  152. }
  153.  
  154. /*
  155.  * NAME:    timer->set()
  156.  * DESCRIPTION:    set timer to specific (positive) value
  157.  */
  158. void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
  159.            unsigned long numer, unsigned long denom)
  160. {
  161.   timer->seconds = seconds;
  162.   if (numer >= denom && denom > 0) {
  163.     timer->seconds += numer / denom;
  164.     numer %= denom;
  165.   }
  166.  
  167.   switch (denom) {
  168.   case 0:
  169.   case 1:
  170.     timer->fraction = 0;
  171.     break;
  172.  
  173.   case MAD_TIMER_RESOLUTION:
  174.     timer->fraction = numer;
  175.     break;
  176.  
  177.   case 1000:
  178.     timer->fraction = numer * (MAD_TIMER_RESOLUTION /  1000);
  179.     break;
  180.  
  181.   case 8000:
  182.     timer->fraction = numer * (MAD_TIMER_RESOLUTION /  8000);
  183.     break;
  184.  
  185.   case 11025:
  186.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
  187.     break;
  188.  
  189.   case 12000:
  190.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
  191.     break;
  192.  
  193.   case 16000:
  194.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
  195.     break;
  196.  
  197.   case 22050:
  198.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
  199.     break;
  200.  
  201.   case 24000:
  202.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
  203.     break;
  204.  
  205.   case 32000:
  206.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
  207.     break;
  208.  
  209.   case 44100:
  210.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
  211.     break;
  212.  
  213.   case 48000:
  214.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
  215.     break;
  216.  
  217.   default:
  218.     timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
  219.     break;
  220.   }
  221.  
  222.   if (timer->fraction >= MAD_TIMER_RESOLUTION)
  223.     reduce_timer(timer);
  224. }
  225.  
  226. /*
  227.  * NAME:    timer->add()
  228.  * DESCRIPTION:    add one timer to another
  229.  */
  230. void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
  231. {
  232.   timer->seconds  += incr.seconds;
  233.   timer->fraction += incr.fraction;
  234.  
  235.   if (timer->fraction >= MAD_TIMER_RESOLUTION)
  236.     reduce_timer(timer);
  237. }
  238.  
  239. /*
  240.  * NAME:    timer->multiply()
  241.  * DESCRIPTION:    multiply a timer by a scalar value
  242.  */
  243. void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
  244. {
  245.   mad_timer_t addend;
  246.   unsigned long factor;
  247.  
  248.   factor = scalar;
  249.   if (scalar < 0) {
  250.     factor = -scalar;
  251.     mad_timer_negate(timer);
  252.   }
  253.  
  254.   addend = *timer;
  255.   *timer = mad_timer_zero;
  256.  
  257.   while (factor) {
  258.     if (factor & 1)
  259.       mad_timer_add(timer, addend);
  260.  
  261.     mad_timer_add(&addend, addend);
  262.     factor >>= 1;
  263.   }
  264. }
  265.  
  266. /*
  267.  * NAME:    timer->count()
  268.  * DESCRIPTION:    return timer value in selected units
  269.  */
  270. signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
  271. {
  272.   switch (units) {
  273.   case MAD_UNITS_HOURS:
  274.     return timer.seconds / 60 / 60;
  275.  
  276.   case MAD_UNITS_MINUTES:
  277.     return timer.seconds / 60;
  278.  
  279.   case MAD_UNITS_SECONDS:
  280.     return timer.seconds;
  281.  
  282.   case MAD_UNITS_DECISECONDS:
  283.   case MAD_UNITS_CENTISECONDS:
  284.   case MAD_UNITS_MILLISECONDS:
  285.  
  286.   case MAD_UNITS_8000_HZ:
  287.   case MAD_UNITS_11025_HZ:
  288.   case MAD_UNITS_12000_HZ:
  289.   case MAD_UNITS_16000_HZ:
  290.   case MAD_UNITS_22050_HZ:
  291.   case MAD_UNITS_24000_HZ:
  292.   case MAD_UNITS_32000_HZ:
  293.   case MAD_UNITS_44100_HZ:
  294.   case MAD_UNITS_48000_HZ:
  295.  
  296.   case MAD_UNITS_24_FPS:
  297.   case MAD_UNITS_25_FPS:
  298.   case MAD_UNITS_30_FPS:
  299.   case MAD_UNITS_48_FPS:
  300.   case MAD_UNITS_50_FPS:
  301.   case MAD_UNITS_60_FPS:
  302.   case MAD_UNITS_75_FPS:
  303.     return timer.seconds * (signed long) units +
  304.       (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
  305.                    units);
  306.  
  307.   case MAD_UNITS_23_976_FPS:
  308.   case MAD_UNITS_24_975_FPS:
  309.   case MAD_UNITS_29_97_FPS:
  310.   case MAD_UNITS_47_952_FPS:
  311.   case MAD_UNITS_49_95_FPS:
  312.   case MAD_UNITS_59_94_FPS:
  313.     return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
  314.   }
  315.  
  316.   /* unsupported units */
  317.   return 0;
  318. }
  319.  
  320. /*
  321.  * NAME:    timer->fraction()
  322.  * DESCRIPTION:    return fractional part of timer in arbitrary terms
  323.  */
  324. unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
  325. {
  326.   timer = mad_timer_abs(timer);
  327.  
  328.   switch (denom) {
  329.   case 0:
  330.     return timer.fraction ?
  331.       MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;
  332.  
  333.   case MAD_TIMER_RESOLUTION:
  334.     return timer.fraction;
  335.  
  336.   default:
  337.     return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
  338.   }
  339. }
  340.  
  341. #if 0
  342. /*
  343.  * NAME:    timer->string()
  344.  * DESCRIPTION:    write a string representation of a timer using a template
  345.  */
  346. void mad_timer_string(mad_timer_t timer,
  347.               char *dest, char const *format, enum mad_units units,
  348.               enum mad_units fracunits, unsigned long subparts)
  349. {
  350.   unsigned long hours, minutes, seconds, sub;
  351.   unsigned int frac;
  352.  
  353.   timer = mad_timer_abs(timer);
  354.  
  355.   seconds = timer.seconds;
  356.   frac = sub = 0;
  357.  
  358.   switch (fracunits) {
  359.   case MAD_UNITS_HOURS:
  360.   case MAD_UNITS_MINUTES:
  361.   case MAD_UNITS_SECONDS:
  362.     break;
  363.  
  364.   case MAD_UNITS_DECISECONDS:
  365.   case MAD_UNITS_CENTISECONDS:
  366.   case MAD_UNITS_MILLISECONDS:
  367.  
  368.   case MAD_UNITS_8000_HZ:
  369.   case MAD_UNITS_11025_HZ:
  370.   case MAD_UNITS_12000_HZ:
  371.   case MAD_UNITS_16000_HZ:
  372.   case MAD_UNITS_22050_HZ:
  373.   case MAD_UNITS_24000_HZ:
  374.   case MAD_UNITS_32000_HZ:
  375.   case MAD_UNITS_44100_HZ:
  376.   case MAD_UNITS_48000_HZ:
  377.  
  378.   case MAD_UNITS_24_FPS:
  379.   case MAD_UNITS_25_FPS:
  380.   case MAD_UNITS_30_FPS:
  381.   case MAD_UNITS_48_FPS:
  382.   case MAD_UNITS_50_FPS:
  383.   case MAD_UNITS_60_FPS:
  384.   case MAD_UNITS_75_FPS:
  385.     {
  386.       unsigned long denom;
  387.  
  388.       denom = MAD_TIMER_RESOLUTION / fracunits;
  389.  
  390.       frac = timer.fraction / denom;
  391.       sub  = scale_rational(timer.fraction % denom, denom, subparts);
  392.     }
  393.     break;
  394.  
  395.   case MAD_UNITS_23_976_FPS:
  396.   case MAD_UNITS_24_975_FPS:
  397.   case MAD_UNITS_29_97_FPS:
  398.   case MAD_UNITS_47_952_FPS:
  399.   case MAD_UNITS_49_95_FPS:
  400.   case MAD_UNITS_59_94_FPS:
  401.     /* drop-frame encoding */
  402.     /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
  403.     {
  404.       unsigned long frame, cycle, d, m;
  405.  
  406.       frame = mad_timer_count(timer, fracunits);
  407.  
  408.       cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
  409.  
  410.       d = frame / cycle;
  411.       m = frame % cycle;
  412.       frame += (10 - 1) * 2 * d;
  413.       if (m > 2)
  414.     frame += 2 * ((m - 2) / (cycle / 10));
  415.  
  416.       frac    = frame % -fracunits;
  417.       seconds = frame / -fracunits;
  418.     }
  419.     break;
  420.   }
  421.  
  422.   switch (units) {
  423.   case MAD_UNITS_HOURS:
  424.     minutes = seconds / 60;
  425.     hours   = minutes / 60;
  426.  
  427.     sprintf(dest, format,
  428.         hours,
  429.         (unsigned int) (minutes % 60),
  430.         (unsigned int) (seconds % 60),
  431.         frac, sub);
  432.     break;
  433.  
  434.   case MAD_UNITS_MINUTES:
  435.     minutes = seconds / 60;
  436.  
  437.     sprintf(dest, format,
  438.         minutes,
  439.         (unsigned int) (seconds % 60),
  440.         frac, sub);
  441.     break;
  442.  
  443.   case MAD_UNITS_SECONDS:
  444.     sprintf(dest, format,
  445.         seconds,
  446.         frac, sub);
  447.     break;
  448.  
  449.   case MAD_UNITS_23_976_FPS:
  450.   case MAD_UNITS_24_975_FPS:
  451.   case MAD_UNITS_29_97_FPS:
  452.   case MAD_UNITS_47_952_FPS:
  453.   case MAD_UNITS_49_95_FPS:
  454.   case MAD_UNITS_59_94_FPS:
  455.     if (fracunits < 0) {
  456.       /* not yet implemented */
  457.       sub = 0;
  458.     }
  459.  
  460.     /* fall through */
  461.  
  462.   case MAD_UNITS_DECISECONDS:
  463.   case MAD_UNITS_CENTISECONDS:
  464.   case MAD_UNITS_MILLISECONDS:
  465.  
  466.   case MAD_UNITS_8000_HZ:
  467.   case MAD_UNITS_11025_HZ:
  468.   case MAD_UNITS_12000_HZ:
  469.   case MAD_UNITS_16000_HZ:
  470.   case MAD_UNITS_22050_HZ:
  471.   case MAD_UNITS_24000_HZ:
  472.   case MAD_UNITS_32000_HZ:
  473.   case MAD_UNITS_44100_HZ:
  474.   case MAD_UNITS_48000_HZ:
  475.  
  476.   case MAD_UNITS_24_FPS:
  477.   case MAD_UNITS_25_FPS:
  478.   case MAD_UNITS_30_FPS:
  479.   case MAD_UNITS_48_FPS:
  480.   case MAD_UNITS_50_FPS:
  481.   case MAD_UNITS_60_FPS:
  482.   case MAD_UNITS_75_FPS:
  483.     sprintf(dest, format, mad_timer_count(timer, units), sub);
  484.     break;
  485.   }
  486. }
  487. #endif
  488.